Skip to content

feat(providers): add CodeBuddy CN credit usage provider - #269

Open
dong5945 wants to merge 2 commits into
nesszer:mainfrom
dong5945:pr/add-codebuddy-cn
Open

feat(providers): add CodeBuddy CN credit usage provider#269
dong5945 wants to merge 2 commits into
nesszer:mainfrom
dong5945:pr/add-codebuddy-cn

Conversation

@dong5945

@dong5945 dong5945 commented Aug 7, 2026

Copy link
Copy Markdown

Summary

Adds a CodeBuddy CN provider so Win-CodexBar can show subscription credit remaining / used totals for Tencent CodeBuddy (codebuddy.cn).

What it tracks

  • Account credit packages via POST https://www.codebuddy.cn/billing/meter/get-user-resource
  • Summed CapacitySize / CapacityUsed / CapacityRemain across packages
  • Optional earliest package expire time as reset

Auth sources (priority)

  1. Manual Cookie header (Settings / token accounts)
  2. %USERPROFILE%\.codebuddy\cb_cookie.txt (shared with statusline helpers)
  3. Browser cookies for codebuddy.cn
  4. Auto fallback: ~/.codebuddy/cb_credits.json normalized cache

Notes

  • Uses a Chrome UA without Edg/ (EdgeOne WAF rejects Edge UAs on this path)
  • Package codes can be overridden with CB_PACKAGE_CODES when an account returns empty Accounts
  • Default-disabled in the provider catalog

Test plan

  • cargo test -p codexbar --lib providers::codebuddy
  • Enable CodeBuddy in Settings → paste Cookie from plans-usage Network tab → refresh
  • Confirm remaining/total credits match https://www.codebuddy.cn/profile/plans-usage

Scope

CN CodeBuddy only (codebuddy.cn). International codebuddy.ai can be a follow-up.


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.

Add a cookie-backed CodeBuddy CN provider that reads remaining credits from get-user-resource, with fallbacks for ~/.codebuddy/cb_cookie.txt and the local cb_credits.json cache. Wire ProviderId, factory, token accounts, and tray/settings catalog entries.
@Finesssee

Copy link
Copy Markdown
Collaborator

Thanks for the PR, I will review it ASAP.

Shorten tray metric text to 'N / total left', ellipsis long reset lines in the card row, retry transient WAF/proxy errors, and persist a local credits cache after successful web fetches for Auto fallback.

@Finesssee Finesssee left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

REQUEST_CHANGES — the provider itself is clean and well-tested, but three things must move before merge: the repo's own CI gates fail, and two boundary issues in the new module need fixing while the code is fresh.

Blockers

1. Repo gates do not pass

The fork's checked-in CI (pr-check.yml) runs cargo fmt --all --check, cargo clippy --workspace --all-targets -- -D warnings, and cargo test --workspace. At head SHA 9fa487de:

  • cargo fmt --all --check fails (5 spots): rust/src/core/provider_factory.rs:9 (the CodeBuddyProvider import is out of sort order), rust/src/providers/codebuddy/mod.rs:16 (serde_json::{json, Value}{Value, json}), and codebuddy/mod.rs:148,180,369.
  • cargo clippy --workspace --all-targets -- -D warnings fails: exactly 3 net-new clippy::collapsible_if warnings — rust/src/providers/codebuddy/mod.rs:175, :210, :538. Base (main @ 02971a79) is clean for these.

Note: the fork's PR checks did not run these gates — the only check-run on the head commit is [code]smith (skipped). So this is not CI catching it; the bar fails locally. Please run cargo fmt --all, collapse the 3 nested if let (let-chains or a small helper), and confirm all three gates pass before re-requesting review.

2. Cache persistence round-trips through the display label (codebuddy/mod.rs:437-480)

write_credits_cache_from_snapshot recovers remaining/total by re-parsing its own formatted reset_description ("1,234 / 5,678 left") via parse_short_credits_desc, and writes 0/0/0 on any deviation (unwrap_or((0.0, 0.0))). That couples the cache schema to tray-label formatting and can silently persist a poisoned-zero cache that Auto mode later serves as real data. Display text must not be persistence input: have the API parsing produce a typed CreditTotals { total, used, remaining, reset } (the f64s already exist at snapshot_from_api_payload) and let both snapshot formatting and cache writing consume it. parse_short_credits_desc should become cache-read-only.

3. Auto fallback masks auth failure (codebuddy/mod.rs:616-624)

Both Err(err) if matches!(ctx.source_mode, SourceMode::Auto) => self.fetch_local_cache().or(Err(err)) arms catch every web error, including ProviderError::AuthRequired (401/403). An expired cookie then surfaces as a stale "cli" success, hiding the exact re-auth signal the user needs. Please propagate AuthRequired and fall back to the local cache only for explicitly transient/unavailable errors (network, 429/5xx, WAF-HTML).

Non-blocking (follow-up, not required here)

is_retryable_error (codebuddy/mod.rs:498) decides retryability by string-matching its own formatted error messages; long-term that should become a typed transient/permanent classification at the error-construction site.

Strengths worth keeping

Provider layering is clean: everything CodeBuddy-specific stays inside the new module; registry insertions (ProviderId, all(), as_str, display_name, domain, from_str, token_accounts, provider_settings) follow the fork's existing insertion-order convention; reuse of browser_cookie_header, credentialed_http_client_builder, and the core usage types is correct. No file crosses the 1k threshold because of this PR (provider.rs was already over; the +9 here is unavoidable registry cost), and tests are real: all 6 module tests plus the touched core::provider/core::provider_factory registry tests pass at head.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants